#region Usings

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using Karma.Framework.Core.Domain.Tools.Import.Configuration.Fluent;
using Karma.Framework.Core.IoC;
using log4net;
using Karma.Framework.Core.Domain.Tools.Import.Extension;
using Karma.Framework.Core.Utils;

#endregion

namespace Karma.Framework.Core.Domain.Tools.Import.Configuration
{
    [DebuggerNonUserCode]
    public class ImporterConfiguration
    {
        private static readonly ILog LOG = LogManager.GetLogger(typeof (ImporterConfiguration).Name);
       
        private static string _domainAssembly;

        private static Type[] _excludedList;

        private static EntityConfiguration[] _importableList;

        private static bool _isInitialized;

        public static Type[] ExcludedTypes
        {
            get
            {
                if (!_isInitialized)
                {
                    Initialize();
                }
                return _excludedList;
            }
        }

        public static EntityConfiguration[] ImportableEntities
        {
            get
            {
                if (!_isInitialized)
                {
                    Initialize();
                }
                return _importableList;
            }
        }

        public static string DomainAssembly
        {
            get
            {
                if (!_isInitialized)
                {
                    Initialize();
                }
                return _domainAssembly;
            }
        }

        private static IList<Type> _listerners;

        public static IList<Type> Listerners
        {
            get
            {
                return _listerners;
            }
        }

        public static void Initialize()
        {
            if (LOG.IsDebugEnabled)
            {
                LOG.Debug("Configuring Importer");
            }
            var section = (ImporterConfigurationSectionHandler)
                          ConfigurationManager.GetSection(
                              ImporterConfigurationSectionHandler.SECTION_NAME);

            var asm = Assembly.Load(section.DomainAssembly);
            _domainAssembly = section.DomainAssembly;
            var configurations = (from c in asm.GetTypes()
                                  where typeof (Fluent.ImporterConfiguration).IsAssignableFrom(c)
                                  select (Fluent.ImporterConfiguration)Activator.CreateInstance(c));

            var importables = new List<EntityConfiguration>();
            var listeners = new List<Type>();
            var excluded = new List<Type>();
            foreach (var configuration in configurations)
            {
                importables.AddRange(configuration.ImportableTypes);
                listeners.AddRange(configuration.Listeners);
                excluded.AddRange(configuration.ExcludedTypes);
            }

            _importableList = importables.ToArray();
            _excludedList = excluded.ToArray();
            _listerners = listeners.ToArray();

            if (LOG.IsDebugEnabled)
            {
                LOG.Debug(string.Format("Importable entities list: {0}", _importableList.ItemsToString()));
                LOG.Debug(string.Format("Excluded types list: {0}", _excludedList.ItemsToString()));
                LOG.Debug(string.Format("Listeners fount: [{0}]", _listerners.ItemsToString()));
            }
            _isInitialized = true;
        }
    }
}